package tablero;

import java.util.Random;

import tablero.Posicion.Direccion;
import tablero.Tablero.Estado;

public class Espacio {
	public Tablero tablero; // cuadricula de movimientos
	public boolean hayMisil; // indica sihay misil
	public boolean alienVivo;
	
	public Posicion defensor; // situacion del defensor
	public Posicion misil; // situacion del misil
	public Posicion alien; // situacion del alien
	
	public int N;
	
	public Espacio(int n){
		hayMisil = false;
		alienVivo = false;
		defensor = null;
		misil = null;
		alien = null;
		N = n;
	}

	/**
	 * 1. Inicializa el tablero con las casillas vacias
	 * 2. Inicializar la posicion del defensor
	 * 3. Inicializa la posicion del alien
	 */
	public void generarPartida(){
		tablero = new Tablero(N);
		
		hayMisil = false;
		alienVivo = false;
		defensor = null;
		misil = null;
		alien = null;
		
		inicializarDefensor();
		inicializarAlien();
		
	}
	
	public void generarPartida4000(){
		tablero = new Tablero(N);
		
		hayMisil = false;
		alienVivo = false;
		defensor = null;
		misil = null;
		alien = null;
		
		// prueba
		defensor = new Posicion(6, N-1);
		tablero.setEstado(defensor, Estado.defensor);
		alienVivo = true;
		alien = new Posicion(18, 0);
		alien.direccion = Direccion.este;
		tablero.setEstado(alien, Estado.alien);
		
	}
	
	/**
	 * Inicializa la posicion del defensor y se actualiza el tablero
	 * Su coor y debe ser la maxima, y su coord x aleatoria
	 * 
	 */
	private void inicializarDefensor() {
		defensor = new Posicion(new Random().nextInt(N), N-1);
		tablero.setEstado(defensor, Estado.defensor);
	}

	/**
	 * Inicializa la posicion del alien y actualiza el tablero
	 * Su coord x es aleatoria, y la coord y entre las 6 primeras filas
	 */
	private void inicializarAlien() {
		alienVivo = true;
		Random r = new Random();
		alien = new Posicion(r.nextInt(N), r.nextInt(6)); // FIXME r.nextInt(6)
		alien.generarDireccionAleatoria();
		tablero.setEstado(alien, Estado.alien);
	}
	
	/**
	 * Calcula los avances del misil y del alienen el tablero. Si se cruzan, la funcion
	 * calcula la disancia entre ellos al momento.
	 * 
	 * @return
	 */
	public int avanzarTiempo(){
		
		// avanza el alien		
		tablero.setEstado(alien, Estado.libre); // posicion se queda libre
		
		if (alienVivo){
			if (alien.direccion == Direccion.este){ // dir este - derecha				
				if (alien.x < N-1){
					alien.x += 1; // der
				} else {
					alien.setDireccion(Direccion.oeste);
					alien.y += 1; // baja
				}				
			} else{ // dis oeste 
				if (alien.x > 0){
					alien.x -= 1; // izq
				} else{
					alien.setDireccion(Direccion.este);
					alien.y += 1; // baja
				}
			}			
			tablero.setEstado(alien, Estado.alien);	// nueva pos misil
		}

		int distancia = 0;
		
		// misil
		if(hayMisil && alienVivo){
			if (misil.y > 0){
				
				tablero.setEstado(misil, Estado.libre); // queda libre
				
				alienVivo = !(misil.y == alien.y && misil.x == alien.x); // han chocado y no avanzo porque se han destruido 
				
				misil.y--; // sube casilla
				tablero.setEstado(misil, Estado.misil); // nueva pos misil
				
				alienVivo = !(misil.y == alien.y && misil.x == alien.x); // han chocado
				
				if (misil.y == alien.y && misil.x != alien.x){ // misma columna, distinta fila
					distancia = Math.abs(misil.x - alien.x);
				} 		
			} else{
				tablero.setEstado(misil, Estado.libre);
				hayMisil = false;
			}	
		}
		return distancia;
	}
	
	
	/**
	 * Comprueba si se ha llegado al final del juego, bien porque 
	 * el alien haya aterrizado o por que haya sido alcanzado por el misil
	 * 
	 * Devuelve un array de 2 booleanos, la pos 0 indica que si el juego ha terminado o no
	 * y la pos 1 si el jugador gana/pierda 
	 * @return 
	 */
	public boolean[] terminacion(){
		boolean[] param = new boolean[] {false,false};
		
		if (alien.y == (N-1)){ // el alien ha aterrizado
			param[0] = true;
			param[1] = false;
		}else if(hayMisil && misil.x == alien.x &&  misil.y == alien.y){ // alien alcanzado por misil
			param[0] = true;
			param[1] = true;
		}
		return param;
	}
	
	public boolean termina(){
		return ((alien.y == (N-1)) || (hayMisil && misil.x == alien.x &&  misil.y == alien.y));	
	}
	
	
	/**
	 * Devuelve si el alien y el defensor se alejan 
	 * @return
	 */
	public boolean seAlejanAlienDefensor(){
		boolean seAlejan = false;
		
		if (alien.x > defensor.x)
			seAlejan = alien.direccion == Direccion.este;
		else
			seAlejan = alien.direccion == Direccion.oeste;
		
		return seAlejan;
	}
	
	
	public Tablero getTablero() {
		return tablero;
	}

	public boolean hayMisil() {
		return hayMisil;
	}
	
	public void setHayMisil(boolean hay) {
		hayMisil = hay;
	}

	public Posicion getDefensor() {
		return defensor;
	}

	public Posicion getMisil() {
		return misil;
	}

	public Posicion getAlien() {
		return alien;
	}

	public int getN() {
		return N;
	}
	
	
	
	
}